package com.hxx.day7;

import org.junit.Test;

/**
 * 当前线程可以调用另一个线程的join方法，
 * 调用后当前线程会被阻塞不再执行，
 * 直到被调用的线程执行完毕，当前线程才会执行
 */
public class TestDemo5 {

    public static void main(String[] args) {
        //创建线程
        Runnable runnable = () -> {
            for (int index = 0; index < 10; index++) {
                String name = Thread.currentThread().getName();
                System.out.println(name +"---线程执行了"+index+"次");
            }
        };
        Thread thread1 = new Thread(runnable,"线程1");
        Thread thread2 = new Thread(runnable,"线程2");

        thread1.start();

        try {
            //当前线程阻塞，等待thread1执行完毕
            thread1.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        thread2.start();
    }

    /**
     * 如果我们的线程正在睡眠，可以采用interrupt进行中断
     * 中断会抛出InterruptedException异常
     * @throws InterruptedException
     */
    @Test
    public void testInterrupt() throws InterruptedException {
        //创建线程
        Runnable runnable = () -> {
            for (int i=1; i<1000; i++) {
                System.out.println(Thread.currentThread().getName() + "," + i);
                if (i % 50 == 0) {
                    try {
                        Thread.sleep(100);
                    }catch(Exception e) {
                        System.out.println("-------中断-------");
                        break;
                    }
                }
            }
        };
        Thread thread1 = new Thread(runnable,"线程1");
        thread1.start();
        try {
            Thread.sleep(300);
        }catch(Exception e) {
            e.printStackTrace();
        }
        //中断睡眠中的线程
        thread1.interrupt();
    }

    /**
     * 正确的退出一个线程
     */
    private volatile boolean flag = false;
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
    @Test
    public void testInterrupt2() throws InterruptedException {

        //创建线程
        Runnable runnable = () -> {
            for (int i=1; i<100; i++) {
                System.out.println(Thread.currentThread().getName() + "," + i);
                if (flag) {
                   break;
                }
            }
        };
        Thread thread1 = new Thread(runnable,"线程1");
        thread1.start();
        try {
            Thread.sleep(300);
        }catch(Exception e) {
            e.printStackTrace();
        }
        //停止线程
        setFlag(true);
    }

    /**
     * 同步锁的使用前的案例
     * 使用一个局部变量
     */
    @Test
    public void testSync1(){
        //创建线程
        Runnable runnable = () -> {
            int sum = 0;
            for (int i=1; i<6; i++) {
                sum += i;
            }
            System.out.println(Thread.currentThread().getName() + "---sum=" + sum);
        };
        Thread thread1 = new Thread(runnable,"线程1");
        Thread thread2 = new Thread(runnable,"线程2");
        thread1.start();
        thread2.start();
    }
    /**
     * 同步锁的使用前的案例
     * 使用一个成员变量
     * 同一个对象创建了两个线程，每个线程都有自己的sum变量
     */
    private int sum = 0;
    @Test
    public void testSync2(){
        //创建线程
        Runnable runnable = () -> {
            for (int i=1; i<6; i++) {
                sum += i;
            }
            System.out.println(Thread.currentThread().getName() + "---sum=" + sum);
        };
        Thread thread1 = new Thread(runnable,"线程1");
        Thread thread2 = new Thread(runnable,"线程2");
        thread1.start();
        thread2.start();
    }
    /**
     * 使用同步锁
     */
    @Test
    public void  testSync3(){
        //创建线程
        Runnable runnable = () -> {
            //同步锁:锁块
            synchronized (this) {
                for (int i = 1; i < 6; i++) {
                    sum += i;
                }
                System.out.println(Thread.currentThread().getName() + "---sum=" + sum);
                sum = 0;
            }
        };
        Thread thread1 = new Thread(runnable,"线程1");
        Thread thread2 = new Thread(runnable,"线程2");
        thread1.start();
        thread2.start();
    }

}


























